import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.channel.unix.DomainSocketAddress;
import io.netty.handler.codec.http.*;
import io.netty.handler.stream.ChunkedWriteHandler;
import sun.org.mozilla.javascript.internal.ast.CatchClause;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.URI;
import java.net.URISyntaxException;

public class HttpServerRequestHandler extends SimpleChannelInboundHandler<FullHttpRequest> { // (1)

	@Override
	protected void channelRead0(ChannelHandlerContext ctx, FullHttpRequest msg) throws Exception {
		System.out.println("浏览器请求====================");
		System.out.println(msg);
		System.out.println();
		doWork(ctx, msg);
	}

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { // (4)
		// Close the connection when an exception is raised.
		cause.printStackTrace();
		ctx.close();
	}

	private void doWork(final ChannelHandlerContext ctx, final FullHttpRequest msg) {
		int port = 80;
		String host = msg.uri();
		if (host.startsWith("https://")) {
			host = host.replaceFirst("https://", "");
			port = 443;
		} else if (host.startsWith("http://")) {
			host = host.replaceFirst("http://", "");
			port = 80;
		}
		int i = host.indexOf("/");
		host = host.substring(0, i);

		EventLoopGroup workerGroup = new NioEventLoopGroup();
		try {
			Bootstrap b = new Bootstrap();
			b.group(workerGroup);
			b.channel(NioSocketChannel.class);
//			b.option(ChannelOption.SO_KEEPALIVE, true);
			b.handler(new ChannelInitializer<SocketChannel>() {
				@Override
				public void initChannel(SocketChannel ch) throws Exception {

					ch.pipeline().addLast("http-decoder",
							new HttpRequestEncoder());
					// 聚合器，把多个消息转换为一个单一的FullHttpRequest或是FullHttpResponse
					ch.pipeline().addLast("http-aggregator",
							new HttpObjectAggregator(65536));
//							// 服务端，对响应编码
//							ch.pipeline().addLast("http-encoder",
//									new HttpResponseEncoder());
					// 块写入处理器
					ch.pipeline().addLast("http-chunked",
							new ChunkedWriteHandler());
					ch.pipeline().addLast(new HttpServerResponseHandler(ctx, msg));
				}
			});

			// Start the client.
			ChannelFuture f = b.connect(host, port).sync(); // (5)

			// Wait until the connection is closed.
			f.channel().closeFuture().sync();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			workerGroup.shutdownGracefully();
		}

		ctx.close();
	}
}

